﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using System;
public class Inventory : MonoBehaviour {
	[Serializable]
	public struct InventoryItem {
		public string type;
		public Weapon.WeaponType fireMode;
		public float damage;
		public float accuracy;
		public float fireRate;
		public int clipSize;
		public float reloadTime;
		public InventoryItem(string type, Weapon.WeaponType fireMode, float damage, float accuracy, float fireRate, int clipSize, float reloadTime) {
			this.type = type;
			this.fireMode = fireMode;
			this.damage = damage;
			this.accuracy = accuracy;
			this.fireRate = fireRate;
			this.clipSize = clipSize;
			this.reloadTime = reloadTime;
		}
	}
	public Sprite pistol;
	public Sprite laser;
	public Sprite shotGun;
	public Sprite machineGun;
	public Sprite key;
	public Sprite armour;
	public Sprite testSprite;
	public GameObject slot;
	public List<InventoryItem> items = new List<InventoryItem>();
	public List<GameObject> slots = new List<GameObject>();
	List<GameObject> buttons = new List<GameObject>();
	public Vector2 gridSize = new Vector2(5,5);
	public RectTransform holder;
	public GameObject defualtItem;
	public GameStateManager manager;
	public InventoryItem weapon1, weapon2;
	public GameObject weaponSlot1;
	public GameObject weaponSlot2;
	public GameObject armourSlot;
	public GameObject garbageSlot;
	public GameObject text;
	float otherWeaponAmmo = 0;
	bool weaponEquipped = false;
	int currentWeapon = 0;
	void Awake () {
		if (GameObject.FindGameObjectsWithTag ("StateManager").Length > 1) {
			Destroy (gameObject);
			return;
		}
		GenerateSlots ();
		holder.gameObject.SetActive(false);
		fillGrid();
		if(items[26].type == "Empty" && items[25].type == "Empty") {
			GetComponent<GameStateManager>().player.transform.Find("Torso").GetComponent<Weapon>().enabled = false;
			weaponEquipped = false;
			ChangeWeapons(0);
		}
		else {
			SetWeapons(items[25], 0);
			SetWeapons(items[26], 1);
			ChangeProtection(items[27].damage);
		}
	}
	public void AfterLoad(){
		if (items [26].type == "Empty" && items [25].type == "Empty") {
			GetComponent<GameStateManager> ().player.transform.Find ("Torso").GetComponent<Weapon> ().enabled = false;
			weaponEquipped = false;
			ChangeWeapons (0);
		} 
		else {
			SetWeapons(items[25], 0);
			SetWeapons(items[26], 1);
			GetComponent<GameStateManager> ().player.transform.Find ("Torso").GetComponent<Weapon> ().enabled = true;
			ChangeProtection(items[27].damage);
		}
	}
	public void AfterLevelLoad() {
		weaponSlot1 = holder.Find("WeaponSlot").gameObject;
		weaponSlot2 = holder.Find("WeaponSlot2").gameObject;
		armourSlot = holder.Find("ArmourSlot").gameObject;
		garbageSlot = holder.Find("GarbageSlot").gameObject;
		text = holder.Find("Panel").Find("Text").gameObject;
		if (items [26].type == "Empty" && items [25].type == "Empty") {
			GetComponent<GameStateManager> ().player.transform.Find ("Torso").GetComponent<Weapon> ().enabled = false;
			weaponEquipped = false;
			ChangeWeapons (0);
		} 
		else {
			SetWeapons(items[25], 0);
			SetWeapons(items[26], 1);
			GetComponent<GameStateManager> ().player.transform.Find ("Torso").GetComponent<Weapon> ().enabled = true;
			ChangeProtection(items[27].damage);
		}
	}
	void Update () {
		if (Input.GetKeyDown (KeyCode.Tab) && !DragHandler.objectBeingDragged) {
			holder.gameObject.SetActive (!holder.gameObject.activeSelf);
			if(!MiniGameManager.getInstance().inProgress) {
				if(GetComponent<GameStateManager>().player.transform.Find("Torso").GetComponent<Weapon>().enabled) GetComponent<GameStateManager>().player.transform.Find("Torso").GetComponent<Weapon>().DisableWeapon();
				else if(!holder.gameObject.activeSelf && weaponEquipped) {
					GetComponent<GameStateManager>().player.transform.Find("Torso").GetComponent<Weapon>().enabled = true;
				}
			}
		}
		if (Input.GetKeyDown (KeyCode.Alpha1)) ChangeWeapons(0);
		if (Input.GetKeyDown (KeyCode.Alpha2)) ChangeWeapons(1);
		if(holder == null) holder = GameObject.Find ("Canvas").transform.Find ("Handler").gameObject.GetComponent<RectTransform>();
		if (manager.lost)
			GetComponent<GameStateManager> ().player.transform.Find ("Torso").GetComponent<Weapon> ().enabled = false;
		if (Input.GetKeyDown (KeyCode.I))
			AddInventoryItem ("Key", Weapon.WeaponType.Auto, 0, 0, 0, 0, 0);
	}

	public void UpdateGrid() {
		foreach (GameObject button in buttons) {
			try {
			Destroy (button.gameObject);
			}
			catch {};
		}
		buttons.RemoveRange (0, buttons.Count);
		for (int i = 0; i < items.Count; i++) {
			if(items[i].type != "Empty") {
				GameObject temp = GameObject.Instantiate(defualtItem);
				temp.GetComponent<RectTransform>().SetParent(slots[i].transform);
				temp.GetComponent<RectTransform>().localScale = new Vector3(1,1,1);
				if(items[i].type == "Armour") 
					temp.GetComponent<Image>().sprite = armour;
				if(items[i].type == "Weapon") {
					switch(items[i].fireMode) {
					case Weapon.WeaponType.Semi:
						temp.GetComponent<Image>().sprite = pistol;
						break;
					case Weapon.WeaponType.Auto:
						temp.GetComponent<Image>().sprite = machineGun;
						break;
					case Weapon.WeaponType.Laser:
						temp.GetComponent<Image>().sprite = laser;
						break;
					case Weapon.WeaponType.Shotgun:
						temp.GetComponent<Image>().sprite = shotGun;
						break;
					}
				}
				buttons.Add(temp);
			}
		}
	}
	public void GenerateSlots() {
		slots.Clear ();
		slots.RemoveRange (0, slots.Count);
		for (int i = 0; i < gridSize.x*gridSize.y; i++) {
			GameObject temp = GameObject.Instantiate(slot);
			temp.GetComponent<RectTransform>().SetParent(holder);
			temp.GetComponent<RectTransform>().localScale = new Vector3(1,1,1);
			temp.GetComponent<RectTransform>().localPosition = new Vector3((i % gridSize.x) * 100 - 100, -(i/(int)gridSize.y) * 100 + (gridSize.y/2f) * 100 - 50, 0); 
			slots.Add(temp);
		}
		slots.Add(weaponSlot1);
		slots.Add(weaponSlot2);
		slots.Add (armourSlot);
		slots.Add (garbageSlot);
	}
	public void AddInventoryItem(InventoryItem item) {
		for(int i = 0; i < slots.Count; i++) {
			if(!slots[i].GetComponent<Slot>().item) {
				items[i] = item;
				GameObject temp = GameObject.Instantiate(defualtItem);
				temp.transform.SetParent(slots[i].transform);
				temp.transform.localScale = new Vector3(1,1,1);
				if(item.type == "Armour") 
					temp.GetComponent<Image>().sprite = armour;
				if(item.type == "Weapon") {
					switch(item.fireMode) {
					case Weapon.WeaponType.Semi:
						temp.GetComponent<Image>().sprite = pistol;
						break;
					case Weapon.WeaponType.Auto:
						temp.GetComponent<Image>().sprite = machineGun;
						break;
					case Weapon.WeaponType.Laser:
						temp.GetComponent<Image>().sprite = laser;
						break;
					case Weapon.WeaponType.Shotgun:
						temp.GetComponent<Image>().sprite = shotGun;
						break;
					}
				}
				break;
			}
		}
	}
	public void AddInventoryItem(string type, Weapon.WeaponType fireMode, float damage, float accuracy, float fireRate, int clipSize, float reloadTime){
		AddInventoryItem(new InventoryItem (type,fireMode,damage,accuracy,fireRate,clipSize,reloadTime));
	}
	public void fillGrid() {
		for(int i = 0; i < gridSize.x * gridSize.y + 4; i++){
			items.Add(new InventoryItem("Empty", Weapon.WeaponType.Auto, 2, 0, 0, 0,0));
		}
	}
	public void SwapSlots(GameObject initialSlot, GameObject endSlot) {
		int index1 = slots.IndexOf(initialSlot);
		int index2 = slots.IndexOf(endSlot);
		InventoryItem item1 = items[index1];
		InventoryItem item2 = items[index2];
		if (index2 == 25 || index2 == 26) {
			SetWeapons (item1, index2 - 25);
		}
		if (index2 == 27)
			ChangeProtection (item1.damage);
		if (index2 == 28) {
			buttons.Remove(DragHandler.objectBeingDragged);
			Destroy(DragHandler.objectBeingDragged);
			item1.type = "Empty";
			if(index1 == 25) {
				weapon1 = new InventoryItem("Empty", Weapon.WeaponType.Semi, 0,0,0,0,0);
				items[25] = new InventoryItem("Empty", Weapon.WeaponType.Semi, 0,0,0,0,0);
			}
			if(index1 == 26) {
				weapon1 = new InventoryItem("Empty", Weapon.WeaponType.Semi, 0,0,0,0,0);
				items[26] = new InventoryItem("Empty", Weapon.WeaponType.Semi, 0,0,0,0,0);
			}
			ChangeWeapons(currentWeapon);
		}

		items[index1] = item2;
		items[index2] = item1;
		ChangeWeapons(currentWeapon);
	}
	public void ChangeWeapons(int weaponNum = 0) {
		Weapon playerWep = GetComponent<GameStateManager>().player.transform.Find("Torso").GetComponent<Weapon>();
		InventoryItem weaponToSet;
		switch(weaponNum) {
		case 0:
			weaponToSet = items[25];
			break;
		case 1:
			weaponToSet = items[26];
			break;
		default:
			weaponToSet = items[25];
			break;
		}

		if (weaponToSet.type == "Weapon") {
			float temp = playerWep.bulletsLeft;
			weaponEquipped = true;
			playerWep.accuracy = weaponToSet.accuracy;
			playerWep.damage = weaponToSet.damage;
			playerWep.fireRate = weaponToSet.fireRate;
			playerWep.currentType = weaponToSet.fireMode;
			playerWep.clipSize = weaponToSet.clipSize;
			playerWep.reloadTime = weaponToSet.reloadTime;
			playerWep.reloading = false;
			if (weaponNum != currentWeapon) { 
				playerWep.bulletsLeft = otherWeaponAmmo;
				otherWeaponAmmo = temp;
			}
			currentWeapon = weaponNum;
		} else {
			weaponEquipped = false;
			playerWep.clipSize = 0;
		}
		playerWep.UpdateCharacter();
	}
	void SetWeapons(InventoryItem weapon, int weaponNum = 0) {
		Weapon playerWep = GetComponent<GameStateManager>().player.transform.Find("Torso").GetComponent<Weapon>();
		switch(weaponNum) {
		case 0:
			if(currentWeapon == 1) otherWeaponAmmo = weapon.clipSize;
			else playerWep.bulletsLeft = weapon.clipSize;
			weapon1 = weapon;

			break;
		case 1:
			if(currentWeapon == 0) otherWeaponAmmo = weapon.clipSize;
			else playerWep.bulletsLeft = weapon.clipSize;
			weapon2 = weapon;
			break;
		}
		ChangeWeapons(currentWeapon);
	}
	public void UpdateText(GameObject item) {
		if(item) {
			int index = slots.IndexOf(item.transform.parent.gameObject);
			if(items[index].type == "Weapon") {
				text.GetComponent<Text>().text = "";
				switch(items[index].fireMode) {
				case Weapon.WeaponType.Auto:
					text.GetComponent<Text>().text = "Machine Gun\n";
					break;
				case Weapon.WeaponType.Semi:
					text.GetComponent<Text>().text = "Pistol\n";
					break;
				case Weapon.WeaponType.Shotgun:
					text.GetComponent<Text>().text = "Shotgun\n";
					break;
				case Weapon.WeaponType.Laser:
					text.GetComponent<Text>().text = "Laser\n";
					break;
				}
				text.GetComponent<Text>().text += "Damage: " + Mathf.Round(items[index].damage) + "\n";
				text.GetComponent<Text>().text += "Accuracy: " + Mathf.Round(items[index].accuracy) + "\n";
				text.GetComponent<Text>().text += "Fire rate: " + Mathf.Round(items[index].fireRate) + "\n";
				text.GetComponent<Text>().text += "Clip Size: " + items[index].clipSize + "\n";
				text.GetComponent<Text>().text += "Reload Time: " + Mathf.Round(items[index].reloadTime * 10)/10 + "\n";
			}
			else if(items[index].type == "Armour") {
				text.GetComponent<Text>().text = "Armour\n" + Mathf.Round(items[index].damage) + "% protection";
			}
			else text.GetComponent<Text>().text = items[index].type;
		}
		else
			text.GetComponent<Text>().text = "";
	}
	public bool canSwap(GameObject initailSlot, GameObject finalSlot) {
		int index1 = slots.IndexOf (initailSlot);
		int index2 = slots.IndexOf (finalSlot);
		if (index2 < 25 || index2 == 28)
			return true;
		if ((index2 == 25 || index2 == 26) && items [index1].type == "Weapon")
			return true;
		if (index2 == 27 && items [index1].type == "Armour")
			return true;
		return false;
	}
	void ChangeProtection(float amount) {
		GetComponent<GameStateManager> ().player.GetComponent<Player> ().protection = amount/100;
	}
	public bool CheckKey() {
		for(int i = 0; i < items.Count; i++) {
			if(items[i].type == "Key") {
				buttons.Remove(slots[i].GetComponent<Slot>().item);
				Destroy(slots[i].GetComponent<Slot>().item);
				InventoryItem tempItem = new InventoryItem("Empty", Weapon.WeaponType.Semi, 0,0,0,0,0);
				items[i] = tempItem;
				return true;
			}
		}
		return false;
	}
}

